package com.geek.javase.ch13.videodemo.serial;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

/**
 * @Desc TODO
 * @Author chenmin
 * @Date 2025/10/25
 *
 * 序列化时，哪些方式可以确保属性不被序列化至文本介质中？
 * 1.static 属性     静态属性
 * 2.transient 属性  瞬态属性   适合有大量属性需要进行序列化和反序列化操作使用 ， 例如：CopyOnWriteArrayList中 transient ReentrantLock锁
 * 3.implements Externalizable接口，重写方法   适合有少量属性需要进行序列化和反序列化操作使用
 */
public class User implements /*Serializable*/ Externalizable {

    //提供一个固定的序列化版本号
    //serialVersionUID 该版本号的目的在于验证序列化的对象和对应类是否版本匹配
    //private static final long serialVersionUID = 1L;
    private static final long serialVersionUID = 3054249871888749308L;

    private String name;
    private int age;

    //瞬态属性，一旦属性被transient修饰，代表当前属性不会被序列化进文本介质中，将以默认值进行存储
    private transient String pwd;

    //静态属性，不再属于某个对象，而是属于当前类的；序列化：对象信息的字节序列，将字节序列存储至文本介质中
    //静态属性不会被序列化，将以默认值进行存储 0
    private static int count;


    //一旦新增属性，反序列化时会抛出InvalidClassException异常
    //解决方式：implements Serializable接口，生成一个固定的序列化版本号
    private String addr;


    public User() {
    }

    public User(String name, int age, String addr ,  String pwd) {
        this.name = name;
        this.age = age;
        this.addr = addr;
        this.pwd = pwd;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public static int getCount() {
        return count;
    }

    public static void setCount(int count) {
        User.count = count;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "User{name = " + name + ", age = " + age + ", addr = " + addr + ", count = " + count + ", pwd = " + pwd  + "}";
    }

    //指定哪些属性会被序列化
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(this.name);
        out.writeObject(this.age);
    }

    //指定哪些属性会被反序列化（要求读取的顺序必须与序列化时一致）
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        this.name = in.readObject().toString();
        this.age = Integer.parseInt(in.readObject().toString());
        System.out.println("name = "+name +" , age = "+age);
    }
}
